package com.yami.shop.otherservice;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.OrderRefund;
import com.yami.shop.bean.model.User;
import com.yami.shop.service.OrderItemService;
import com.yami.shop.service.OrderRefundService;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 一级分销功能
 */
@Service
public class UserLevelUpgradeService {
    @Autowired
    private UserService userService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private OrderRefundService orderRefundService;

    /**
     * 查询今天偏移7天后,当前要失效的用户
     * @return
     */
    public List<User> getSevenDayExpireMember() {
        Date date = new Date();
        DateTime offset7 = DateUtil.offset(date, DateField.DAY_OF_MONTH, 7);
        DateTime begin = DateUtil.beginOfDay(offset7);
        DateTime end = DateUtil.endOfDay(offset7);

        //查询今天偏移7天后,当前要失效的用户
        List<User> list = userService.lambdaQuery()
                .select(User::getUserId,User::getNickName,User::getUserLevel,User::getUserLevelExpireDate,User::getUserMobile)
                .isNotNull(User::getUserLevel)
                .between(User::getUserLevelExpireDate, begin,end)
                .list();

        return list;
    }


    /**
     * 停用超时会员
     */
    public void deactivateExpireMember() {
        Date date = new Date();

        List<User> list = userService.lambdaQuery()
                .select(User::getUserId)
                .isNotNull(User::getUserLevel)
                .eq(User::getUserLevel,0)//普通会员
                .lt(User::getUserLevelExpireDate, date).list();

        List<String> collect = list.stream().map(u -> u.getUserId()).collect(Collectors.toList());
        if(collect.isEmpty()){
            return;
        }

        userService.lambdaUpdate().set(User::getUserLevel,null).set(User::getUserLevelExpireDate,null)
                .in(User::getUserId,collect).update();
    }


    /**
     * 在会员到期的前 15天 7天 3天 当天,提醒会员到期
     * @param uid
     * @return
     */
    public Map<String,Object> expireDateRemind(String uid) {
        Map<String,Object> rmap=new HashMap<>();

        Date date = new Date();
        DateTime begin = DateUtil.beginOfDay(date);
        DateTime end = DateUtil.endOfDay(date);

        User byId = userService.getById(uid);
        if(byId == null){
            return null;
        }
        if(byId.getUserLevelExpireDate() == null){
            return null;
        }
        //往前推15天
        DateTime offset15 = DateUtil.offset(byId.getUserLevelExpireDate(), DateField.DAY_OF_MONTH, -15);
        if(begin.getTime() <= offset15.getTime() && end.getTime() >= offset15.getTime()){
            //当前日期为超期时间往前的第15天
            rmap.put("expireDate",DateUtil.format(byId.getUserLevelExpireDate(), "yyyy-MM-dd HH:mm:ss"));
            rmap.put("days",15);
            rmap.put("accountNumber",byId.getUserMobile());
            return rmap;
        }


        //往前推7天
        DateTime offset7 = DateUtil.offset(byId.getUserLevelExpireDate(), DateField.DAY_OF_MONTH, -7);
        if(begin.getTime() <= offset7.getTime() && end.getTime() >= offset7.getTime()){
            //当前日期为超期时间往前的第15天
            rmap.put("expireDate",DateUtil.format(byId.getUserLevelExpireDate(), "yyyy-MM-dd HH:mm:ss"));
            rmap.put("days",7);
            rmap.put("accountNumber",byId.getUserMobile());
            return rmap;
        }

        //往前推3天
        DateTime offset3 = DateUtil.offset(byId.getUserLevelExpireDate(), DateField.DAY_OF_MONTH, -3);
        if(begin.getTime() <= offset3.getTime() && end.getTime() >= offset3.getTime()){
            //当前日期为超期时间往前的第15天
            rmap.put("expireDate",DateUtil.format(byId.getUserLevelExpireDate(), "yyyy-MM-dd HH:mm:ss"));
            rmap.put("days",3);
            rmap.put("accountNumber",byId.getUserMobile());
            return rmap;
        }

        //往前推0天
        DateTime offset0 = DateUtil.offset(byId.getUserLevelExpireDate(), DateField.DAY_OF_MONTH, 0);
        if(begin.getTime() <= offset0.getTime() && end.getTime() >= offset0.getTime()){
            //当前日期为超期时间往前的第15天
            rmap.put("expireDate",DateUtil.format(byId.getUserLevelExpireDate(), "yyyy-MM-dd HH:mm:ss"));
            rmap.put("days",0);
            rmap.put("accountNumber",byId.getUserMobile());
            return rmap;
        }

        return null;
    }


    /**
     * 检测下单数量大于等于1升级为普通会员
     * @param uid
     */
    public void autoUpgrade(String uid) {
        User byId = userService.getById(uid);
        if(byId == null){
            return;
        }

        if(byId.getUserLevel() != null){
            return;//用户已成为会员,无需再次查询订单数量升级
        }
        Integer userProdOrderQuantity = getUserProdOrderQuantity(uid);
        if(userProdOrderQuantity > 0){
            User user=new User();
            user.setUserId(uid);
            user.setUserLevel(0);//普通会员
            userService.updateById(user);

            //设置过期时间为一个月后,如果时间内无新订单,无新推荐用户,用户等级设置为无
            DateTime offset = DateUtil.offset(new Date(), DateField.MONTH, 1);
            userService.lambdaUpdate().set(User::getUserLevelExpireDate,offset).eq(User::getUserId,uid).update();
        }
    }

    /**
     * 获取配置项
     * @param key
     * @return
     */
    public String  getValueByConfig(String key) {
        List<String> param_value = jdbcTemplate.query("select param_value from tz_sys_config where param_key = ? ", new RowMapper<String>() {
            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString("param_value");
            }
        }, key);

        if(param_value.isEmpty()){
            return null;
        }else{
            return param_value.get(0);
        }
    }

    /**
     * 获取指定用户的下单数量
     * @param uid
     * @return
     */
    public Integer getUserProdOrderQuantity(String uid) {
        String enableDistributionProdIds = this.getValueByConfig("enable_distribution_prod_ids");
        List<String> prodIds = Arrays.asList(StringUtils.split(enableDistributionProdIds, ","));
        List<Order> list = orderService.lambdaQuery().select(Order::getOrderNumber).eq(Order::getUserId, uid)
                .eq(Order::getIsPayed,1)//已支付
                .list();

        List<String> collect = list.stream().map(o -> o.getOrderNumber()).collect(Collectors.toList());

        //下单数量
        Integer orderQuantity=0;

        for(String orderNumber:collect){
            List<OrderItem> list1 = orderItemService.lambdaQuery()
                    .select(OrderItem::getOrderItemId,OrderItem::getProdCount)
                    .eq(OrderItem::getOrderNumber, orderNumber)
                    .in(OrderItem::getProdId, prodIds).list();
            //共下单了几个
            int sum1 = list1.stream().mapToInt(i -> i.getProdCount()).sum();
            for(OrderItem item:list1){
                List<OrderRefund> list2 = orderRefundService.lambdaQuery()
                        .select(OrderRefund::getGoodsNum)
                        .eq(OrderRefund::getOrderItemId, item.getOrderItemId())
                        .eq(OrderRefund::getReturnMoneySts, 1)//退款成功的
                        .list();

                //本个子订单共退款成功了几单
                int sum = list2.stream().mapToInt(r -> r.getGoodsNum()).sum();

                //本次订单还剩几单没有被退款
                int i = sum1 - sum;
                orderQuantity = orderQuantity +  i;
            }
        }

        return orderQuantity;
    }
}
